﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using M2B.GestionEntretiens.DAL;
using M2B.GestionEntretiens.POCOS;

namespace M2B.GestionEntretiens.BLL
{
    /// <summary>
    /// Cette Classe décrit le service Tests
    /// </summary>
    /// <remarks>
    /// Informations de la classe : 
    /// <list type="bullet">
    /// <item name="authors">Auteur : M2B : Maher SAMMARI</item>
    /// <item name="creation date">Date de création : 01/04/2014</item>
    /// <item name="last modification">Date de dernière modification : 01/04/2014</item>
    /// </list>
    /// </remarks>
    public class TestsManager
    {
        #region Properties
        /// <summary>
        /// Interface unit of work
        /// </summary>
        private IUnitOfWork _unitOfWork;
        #endregion

        #region Constructeurs
        /// <summary>
        /// Constructeur ayant comme paramétre l'interface unit of work
        /// </summary>
        /// <param name="unitOfWork">Unit of Work</param>
        public TestsManager(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
        #endregion

        #region Méthodes
        /// <summary>
        /// Récupération de tous les Tests
        /// </summary>
        /// <returns>Tests</returns>
        public IEnumerable<Test> GetTests(string entityToEnclude)
        {
            return _unitOfWork.TestsRepository.GetAll(entityToEnclude);
        }
        /// <summary>
        /// Récupération d'un Test par Id
        /// </summary>
        /// <param name="id">Identificateur</param>
        /// <returns></returns>
        public Test GetTestById(long id)
        {
            return _unitOfWork.TestsRepository.GetById(id);
        }
        /// <summary>
        /// Création d'un Test
        /// </summary>
        /// <param name="test">Test</param>
        public void CreateTest(Test test)
        {

            if (test != null)
            {
                //La liste des relations à ajouter
                var testQuestions = test.TestQuestions.ToList();
                //La liste des questions à ajouter au test
                var questionsIds = testQuestions.Select(el => el.Question.QuestionId).ToList();
                var questions =
                    _unitOfWork.QuestionsRepository.GetAll().Where(el => questionsIds.Contains(el.QuestionId)).ToList();
                test.TestQuestions = null;
                //Ajout du test
                test.DateCreation = DateTime.Now;
                test.DateModification = DateTime.Now;
                _unitOfWork.TestsRepository.Add(test);
                //Ajout des relations (Test _ quetions)
                foreach (var item in testQuestions)
                {
                    item.Question = questions.FirstOrDefault(el => el.QuestionId == item.Question.QuestionId);
                    item.DateCreation = DateTime.Now;
                    item.DateModification = DateTime.Now;
                    item.Test = test;
                    _unitOfWork.TestQuestionsRepository.Add(item);
                }

                SaveTests();
            }
        }
        /// <summary>
        /// Mise à jour d'un Test
        /// </summary>
        /// <param name="test">Test à mettre à jour</param>
        public void UpdateTest(Test test)
        {
            if (test != null)
            {
                var original = _unitOfWork.TestsRepository.GetById(test.TestId);
                _unitOfWork.TestsRepository.Update(original);
                var originalTestQuestions = original.TestQuestions.ToList();
                original.TestQuestions = null;
                foreach (var item in originalTestQuestions)
                {
                    _unitOfWork.TestQuestionsRepository.Delete(item);
                }

                test.DateCreation = original.DateCreation;
                test.DateTest = original.DateTest;
                var testQuetions = test.TestQuestions.ToList();
                foreach (var item in testQuetions)
                {
                    var question = _unitOfWork.QuestionsRepository.GetById(item.Question.QuestionId);
                    item.Question = question;
                    item.DateCreation = DateTime.Now;
                    item.Test = original;
                    item.DateModification = DateTime.Now;
                }
                test.TestQuestions = null;
                foreach (PropertyDescriptor item in TypeDescriptor.GetProperties(test))
                {
                    item.SetValue(original, item.GetValue(test));
                }
                original.TestQuestions = testQuetions;
                original.DateModification = DateTime.Now;
                SaveTests();
            }
        }
        /// <summary>
        /// Suppression d'un Test
        /// </summary>
        /// <param name="id">Identificateur</param>
        public void DeleteTest(long id)
        {
            var testToDelete = GetTestById(id);
            if (testToDelete != null)
            {
                //Récupération de la liste des relations Test-Question
                var testQuestionsToDelete = testToDelete.TestQuestions.ToList();
                testToDelete.TestQuestions = null;
                //Suppression de la realtion Test-Question
                foreach (var item in testQuestionsToDelete)
                {
                    _unitOfWork.TestQuestionsRepository.Delete(item);
                }
                //Suppression du Test
                _unitOfWork.TestsRepository.Delete(testToDelete);
                SaveTests();
            }

        }
        /// <summary>
        /// Sauvegarde et Commit
        /// </summary>
        public void SaveTests()
        {
            _unitOfWork.Commit();
        }
        #endregion

    }
}
